#include "skin.h"

int refresh_thread(void* arg);
int def_skin_porc(void* object, int message, int wparam, void* lparam);

PSKIN_WINDOW skin_createwindow(int option, int colorformat, int cx, int cy, SKIN_PROC wndProc)
{
    PSKIN_WINDOW p = (PSKIN_WINDOW)malloc(sizeof(SKIN_WINDOW));
    if (p)
    {
        memset(p, 0, sizeof(SKIN_WINDOW));
        if (wndProc)
        {
          p->skin_proc    = wndProc;
        }
        else
        {
          p->skin_proc    = def_skin_porc; // set default skin procedure...
        }
        p->rect.cx      = cx;
        p->rect.cy      = cy;
        p->screen       = SDL_SetVideoMode(cx, cy,colorformat, option);
        p->start_mode   = option;
        p->color_depth  = colorformat;
        if (!p->screen)
        {
            free(p);
            return 0;
        }
        printf("skin window created!\r\n");

        // set interfaces..
        SKIN_OVERRIDE(p,    OnInitWindow,       skin_oninitwindow);
        SKIN_OVERRIDE(p,    OnCloseWindow,      skin_onclosewindow);
        SKIN_OVERRIDE(p,    OnKeyDown,          skin_onkeydown);
        SKIN_OVERRIDE(p,    OnKeyUp,            skin_onkeyup);
        // mouse
        SKIN_OVERRIDE(p,    OnMouseMove,        skin_onmousemove);
        SKIN_OVERRIDE(p,    OnMouseButtonDown,  skin_onmousebuttondown);
        SKIN_OVERRIDE(p,    OnMouseButtonUp,    skin_onmousebuttonup);
        // joystick
        // not implemented at this time...
        // video
        SKIN_OVERRIDE(p,    OnWindowSize,       skin_onwindowsize);
        // paint
        SKIN_OVERRIDE(p,    OnPaint,            skin_onpaint);
        SKIN_OVERRIDE(p,    OnEraseBackGround,  skin_onerasebackground);
        // activated
        SKIN_OVERRIDE(p,    OnActivated,        skin_onactivated);
        // command
        SKIN_OVERRIDE(p,    OnCommand,          skin_oncommand);

        // main bitmap
        p->main_bmp         = SDL_CreateYUVOverlay(cx, cy, SDL_YV12_OVERLAY, p->screen);
        // refresh interval
        p->refresh_interval = 50;
        // create refresh thread..
        //p->refresh_tid      = SDL_CreateThread(refresh_thread, p);

        return p;
    }
    return 0;
}

int refresh_thread(void* arg)
{
    PSKIN_WINDOW p = (PSKIN_WINDOW) arg;
    SDL_Event    e;
    if (p)
    {
        while (p->refresh_interval)
        {
            e.type = SKIN_EVENT_REFRESH;
            e.user.data1 = p;
            SDL_PushEvent(&e);
            SDL_Delay(p->refresh_interval);
        }
    }
    return 0;
}

void        skin_closewindow(PSKIN_WINDOW p)
{
    if (p)
    {
        if (p->clients)
        {
            skin_control_removeall(p);
        }
        if (p->main_bmp)
        {
            SDL_FreeYUVOverlay(p->main_bmp);
            p->main_bmp = 0;
        }
#if (SDL_TTF_USE == 1)
        if (p->default_font)
        {
            TTF_CloseFont(p->default_font);
#if (SKIN_DEBUG == 1)
            printf("Font closed\r\n");
#endif
        }
#endif
        free(p);
#if (SKIN_DEBUG == 1)
        printf("skin closed!!\r\n");
#endif
    }
}


// main window interfaces
int         skin_oninitwindow(void* self)
{
    PSKIN_WINDOW p = (PSKIN_WINDOW) self;
#if (SKIN_DEBUG == 1)
    printf("OnInitWindow()\r\n");
#endif
    return 0;
}

void        skin_onclosewindow(void* self)
{
    PSKIN_WINDOW p = (PSKIN_WINDOW) self;
#if (SKIN_DEBUG == 1)
    printf("OnCloseWindow()\r\n");
#endif
}
// keyboard
int         skin_onkeydown       (void* self, SDL_Event* e)
{
    PSKIN_WINDOW p = (PSKIN_WINDOW) self;
#if (SKIN_DEBUG == 1)
    printf("OnKeyDown(type(%d), which(%d), state(%d), keysym(scancode(%d), sym(%d), mod(%d)))\r\n",  e->key.type,     
                                                                                                     e->key.which,
                                                                                                     e->key.state,
                                                                                                     e->key.keysym.scancode,
                                                                                                     e->key.keysym.sym,
                                                                                                     e->key.keysym.mod);
#endif
    return 0;
}
int         skin_onkeyup          (void* self, SDL_Event* e)
{
    PSKIN_WINDOW p = (PSKIN_WINDOW) self;
#if (SKIN_DEBUG == 1)
    printf("OnKeyUp(type(%d), which(%d), state(%d), keysym(scancode(%d), sym(%d), mod(%d)))\r\n", e->key.type,       
                                                                                                  e->key.which,
                                                                                                  e->key.state,
                                                                                                  e->key.keysym.scancode,
                                                                                                  e->key.keysym.sym,
                                                                                                  e->key.keysym.mod);
#endif
    return 0;
}
// mouse
int         skin_onmousemove      (void* self, SDL_Event* e)
{
    PSKIN_WINDOW p = (PSKIN_WINDOW) self;
    PSKIN_CLIENT control = 0;

    if (p->active)
    {
        return p->active->OnMouseMove(p->active, e);
    }
    // who has mouse focus?
    control = (PSKIN_CLIENT)skin_pt_in_client(p, (int)e->motion.x, (int)e->motion.y);
    if (control)
    {
        if (control->OnMouseMove)
            return control->OnMouseMove(control, e);
    }
#if (SKIN_DEBUG == 1)
    printf("OnMouseMove(type(%d), which(%d), state(%d), x(%d), y(%d), xrel(%d), yrel(%d))\r\n", e->motion.type,
                                                                                                e->motion.which,
                                                                                                e->motion.state,
                                                                                                e->motion.x,
                                                                                                e->motion.y,
                                                                                                e->motion.xrel,
                                                                                                e->motion.yrel);
#endif
    return 0;
}
int         skin_onmousebuttondown(void* self, SDL_Event* e)
{
    PSKIN_WINDOW p = (PSKIN_WINDOW) self;
    PSKIN_CLIENT control = 0;

    if (p->active)
    {
        return p->active->OnMouseButtonDown(p->active, e);
    }
    // who has mouse focus?
    control = (PSKIN_CLIENT)skin_pt_in_client(p, (int)e->motion.x, (int)e->motion.y);
    if (control)
    {
        if (control->OnMouseMove)
            return control->OnMouseButtonDown(control, e);
    }
#if (SKIN_DEBUG == 1)
    printf("OnMouseButtonDown()\r\n");
#endif
    return 0;
}
int         skin_onmousebuttonup  (void* self, SDL_Event* e)
{
    PSKIN_WINDOW p = (PSKIN_WINDOW) self;
    PSKIN_CLIENT control = 0;

    if (p->active)
    {
        return p->active->OnMouseButtonUp(p->active, e);
    }
    // who has mouse focus?
    control = (PSKIN_CLIENT)skin_pt_in_client(p, (int)e->motion.x, (int)e->motion.y);
    if (control)
    {
        if (control->OnMouseMove)
            return control->OnMouseButtonUp(control, e);
    }
#if (SKIN_DEBUG == 1)
    printf("OnMouseButtonUp()\r\n");
#endif
    return 0;
}
// joystick
// not implemented at this time...
// video
int         skin_onwindowsize     (void* self, SDL_Event* e)
{
    PSKIN_WINDOW p = (PSKIN_WINDOW) self;
    p->rect.cx = e->resize.w;
    p->rect.cy = e->resize.h;
    p->screen = SDL_SetVideoMode(   e->resize.w, 
                                    e->resize.h,
                                    p->color_depth, 
                                    p->start_mode);
    if (p->main_bmp)
    {
        // Z8U9GUSTMVVN79QN
        SDL_FreeYUVOverlay(p->main_bmp);
        p->main_bmp = SDL_CreateYUVOverlay(e->resize.w, e->resize.h, SDL_YV12_OVERLAY, p->screen);
        p->OnPaint(p);
    }
#if (SKIN_DEBUG == 1)
    printf("OnWindowSize()\r\n");
#endif
    return 0;
}
// paint
int         skin_onpaint          (void* self)
{
    PSKIN_WINDOW p = (PSKIN_WINDOW) self;
#if (SKIN_DEBUG == 1)
    printf("OnPaint()\r\n");
#endif
    return 0;
}
int         skin_onerasebackground(void* self)
{
    PSKIN_WINDOW p = (PSKIN_WINDOW) self;
#if (SKIN_DEBUG == 1)
    printf("OnEraseBackGround()\r\n");
#endif
    return 0;
}
// activated
int         skin_onactivated(void* self, SDL_Event* e)
{
    PSKIN_WINDOW p = (PSKIN_WINDOW) self;
#if (SKIN_DEBUG == 1)
    printf("OnActivated(type(%d), gain(%d), state(%d))\r\n", e->active.type,
                                                             e->active.gain,
                                                             e->active.state);
#endif
    return 0;
}

int         skin_oncommand       (int event_type, void* control)
{
#if (SKIN_DEBUG == 1)
    printf("OnCommand(%d)\r\n", event_type);
#endif
    return 0;
}

// default skin proc
int def_skin_porc(void* object, int message, int wparam, void* lparam)
{
    switch (message)
    {
    case SDL_VIDEORESIZE:
            {
                    PSKIN_WINDOW p = (PSKIN_WINDOW) object;
                    p->OnWindowSize(object, (SDL_Event*) lparam);
            }
            break;
    case SDL_ACTIVEEVENT:
            {
                    PSKIN_WINDOW p = (PSKIN_WINDOW) object;
                    p->OnActivated(object, (SDL_Event*) lparam);
            }
            break;
    case SDL_KEYDOWN:
            {
                    PSKIN_WINDOW p = (PSKIN_WINDOW) object;
                    p->OnKeyDown(object, (SDL_Event*) lparam);
            }
            break;
    case SDL_KEYUP:
            {
                    PSKIN_WINDOW p = (PSKIN_WINDOW) object;
                    p->OnKeyUp(object, (SDL_Event*) lparam);
            }
            break;
    case SDL_MOUSEMOTION:
            {
                    PSKIN_WINDOW p = (PSKIN_WINDOW) object;
                    p->OnMouseMove(object, (SDL_Event*) lparam);
            }
            break;
    case SDL_MOUSEBUTTONDOWN:
            {
                    PSKIN_WINDOW p = (PSKIN_WINDOW) object;
                    p->OnMouseButtonDown(object, (SDL_Event*) lparam);
            }
            break;
    case SDL_MOUSEBUTTONUP:
            {
                    PSKIN_WINDOW p = (PSKIN_WINDOW) object;
                    p->OnMouseButtonUp(object, (SDL_Event*) lparam);
            }
            break;
    case SDL_JOYAXISMOTION:
            {
#if (SKIN_DEBUG == 1)
                    printf("joystick move in skin client(NI)\r\n");
#endif
            }
            break;
    case SDL_JOYBALLMOTION:
            {
#if (SKIN_DEBUG == 1)
                    printf("joyball move in skin client(NI)\r\n");
#endif
            }
            break;
    case SDL_JOYHATMOTION:
            {
#if (SKIN_DEBUG == 1)
                    printf("joyhat move in skin client(NI)\r\n");
#endif
            }
            break;
    case SDL_JOYBUTTONDOWN:
            {
#if (SKIN_DEBUG == 1)
                    printf("joystick button down in skin client(NI)\r\n");
#endif
            }
            break;
    case SDL_JOYBUTTONUP:
            {
#if (SKIN_DEBUG == 1)
                    printf("joystick button down in skin client(NI)\r\n");
#endif
            }
            break;
    case SDL_SYSWMEVENT:
            {
#if (SKIN_DEBUG == 1)
                    printf("system event(NI)\r\n");
#endif
            }
            break;
    case SDL_VIDEOEXPOSE:
            {
#if (SKIN_DEBUG == 1)
                    printf("videoexpose(NI)\r\n");
#endif
            }
            break;
    case SKIN_EVENT_INITWIN:
            {
                    PSKIN_WINDOW p = (PSKIN_WINDOW) object;
                    p->OnInitWindow(object);
            }
    case SKIN_EVENT_REFRESH:
            {
                    PSKIN_WINDOW p = (PSKIN_WINDOW) object;
                    p->OnPaint(object);
            }
            break;
    }
    return 0;
}